package com.common.utils;

import com.common.model.vo.page.PageList;
import org.apache.commons.collections.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
 * 分页结果转换工具类
 * 功能：把数据库查询到的「全量数据列表」，转换成「带分页信息的PageList对象」
 */
public class PageResultUtils {

    /**
     * 转换全量数据为分页对象
     * @param fullDataList 数据库查询返回的「全量数据」（未分页的所有数据）
     * @param pageNum 当前页码（比如第1页、第2页）
     * @param pageSize 每页显示条数（比如每页显示10条）
     * @param <T> 数据类型（泛型，适配不同类型的列表）
     * @return 带分页信息的PageList对象（包含当前页数据、总条数、总页数等）
     */
    public static <T> PageList<T> convertPageList(List<T> fullDataList, long pageNum, long pageSize) {
        // 1. 初始化分页结果对象（最终要返回的对象）
        PageList<T> pageResult = new PageList<>();
        // 2. 先设置基础分页参数（当前页码、每页条数）
        pageResult.setPageNum(pageNum);
        pageResult.setPageSize(pageSize);

        // 3. 处理全量数据：如果数据为空，直接返回空分页（避免后续计算报错）
        if (CollectionUtils.isEmpty(fullDataList)) {
            pageResult.setTotalCount(0L); // 总条数=0
            pageResult.setTotalPage(0L);  // 总页数=0
            pageResult.setDataList(new ArrayList<>()); // 当前页数据为空列表
            return pageResult;
        }

        // 4. 计算总条数（全量数据的大小）
        long totalCount = fullDataList.size();
        pageResult.setTotalCount(totalCount);

        // 5. 计算总页数（公式：总条数 ÷ 每页条数，向上取整，比如7条数据每页3条=3页）
        // 用BigDecimal确保除法精度，避免整数除法丢失小数（比如7/3=2，向上取整后为3）
        BigDecimal totalCountBig = new BigDecimal(totalCount);
        BigDecimal pageSizeBig = new BigDecimal(pageSize);
        long totalPage = totalCountBig.divide(pageSizeBig, 0, RoundingMode.UP).longValue();
        pageResult.setTotalPage(totalPage);

        // 6. 计算当前页数据的截取范围（startIndex：起始索引，endIndex：结束索引）
        // 起始索引 = (当前页码-1) × 每页条数（比如第2页、每页10条：(2-1)*10=10，从第11条开始）
        long startIndex = (pageNum - 1) * pageSize;
        // 结束索引 = 起始索引 + 每页条数（但不能超过总条数，避免数组越界）
        long endIndex = startIndex + pageSize;
        endIndex = Math.min(endIndex, fullDataList.size()); // 取"结束索引"和"总条数"的较小值

        // 7. 截取当前页数据（subList：左闭右开，比如subList(10,20)是取索引10到19的数据）
        List<T> currentPageData = fullDataList.subList((int)startIndex, (int)endIndex);
        // 8. 把截取后的当前页数据存入分页结果
        pageResult.setDataList(new ArrayList<>(currentPageData)); // 转成ArrayList，避免subList的视图问题

        // 9. 返回最终的分页结果
        return pageResult;
    }

}
